/*****************************************************
 *                                                   *
 *        Template reader      GCW 6/6/94            *
 *                                                   *
 *  Use as  Templread <template_file>                *
 *  to open an Edit window on a Bob source text      *
 *  for the template file given as argument.         *
 *                                                   *
 *****************************************************/

main()
{
 r = newvector(8);
 out = "Pipe:Temp";           // temporary output file
 write(out,read(getarg(1)));
 oscli("Settype "+out+" text");
 oscli("Filer_run "+out);
}

read(file)
{
 local result;
 r[0] = 23;
 r[1] = @(file);
 swi("OS_File",r);
 if (r[6] != &fec) quit("Not a template file\n");
 result = r[2] = @(newstring(r[4]));
 r[0] = 16;
 r[3] = 0;
 swi("OS_File",r);
 return result;
}

write(file,buffer)
{
 local item, fp, offset; 
 if (fp = fopen(file,"w"))
  {
   item = buffer+16;
   offset = word(item);
   while (offset)
    {
      p = buffer+offset;
      inscribe(item,p,fp,p);
      item += 24;
      offset = word(item);
     }
   fclose(fp);
  }
}

inscribe(item,p,fp,buffer)
{
 local size, name, flags, ino, icon, c;
 size = word(item+4); name = $(item+12);
 fprint(fp,"/* "+name+" */\n");
 fprint(fp,"in "+name+"_buf put {\n");
 fprint(fp,string(word(p),10)+";/* xmin */\n"); p += 4;
 fprint(fp,string(word(p),10)+";/* ymin */\n"); p += 4;
 fprint(fp,string(word(p),10)+";/* xmax */\n"); p += 4;
 fprint(fp,string(word(p),10)+";/* ymax */\n"); p += 4;
 fprint(fp,string(word(p),10)+";/* x scroll */\n"); p += 4;
 fprint(fp,string(word(p),10)+";/* y scroll */\n"); p += 4;
 fprint(fp,string(word(p),10)+";/* behind */\n"); p += 4;
 fprint(fp,hex(word(p))+";/* window flags */\n"); p += 4;
 fprint(fp,hex(word(p))+";/* colours */\n"); p += 4;
 fprint(fp,hex(word(p))+";/* scroll colours */\n"); p += 4;
 fprint(fp,string(word(p),10)+";/* work xmin */\n"); p += 4;
 fprint(fp,string(word(p),10)+";/* work ymin */\n"); p += 4;
 fprint(fp,string(word(p),10)+";/* work xmax */\n"); p += 4;
 fprint(fp,string(word(p),10)+";/* work ymax */\n"); p += 4;
 flags = word(p) & (259);
 fprint(fp,hex(word(p))+";/* title icon flags */\n"); p += 4;
 fprint(fp,hex(word(p))+";/* work button flags */\n"); p += 4;
 fprint(fp,string(word(p),10)+";/* sprite area */\n"); p += 4;
 fprint(fp,string(word(p),10)+";/* min width/height */\n"); p += 4;
 p = indir(fp,flags,p);
 fprint(fp,string((ino = word(p)),10)+";/* no. of icons */\n"); p += 4;
 for (icon = 0; icon < ino; icon++)
 {
  fprint(fp,"/* icon "+string(icon,10)+" */\n");
  fprint(fp,string(word(p),10)+";/* xmin */\n"); p += 4;
  fprint(fp,string(word(p),10)+";/* ymin */\n"); p += 4;
  fprint(fp,string(word(p),10)+";/* xmax */\n"); p += 4;
  fprint(fp,string(word(p),10)+";/* ymax */\n"); p += 4;
  flags = word(p) & (259);
  fprint(fp,hex(word(p))+";/* icon flags */\n"); p += 4;
  p = indir(fp,flags,p);
 }
 if (p < buffer+size)
  {
   fprint(fp,"/* Indirected data */\n");
   putc(34,fp);
   while (p < buffer+size)
   {
    c = byte(p++);
    if (c==13)
      if (p < buffer+size)
       {
        putc(34,fp);
        fprint(fp,";\n");
        putc(34,fp);
       }
    if (c!=13)
     putc(c,fp);
   }
   putc(34,fp);
   fprint(fp,";\n");
  }
 fprint(fp,"}\n");
}

/* deal with possible indirection */
indir(fp,flags,q)
{
 local p;
 p = q;
 switch(flags)
 {
  case 0:
    fprint(fp,"/* no data */\n");
    fprint(fp,string(word(p),10)+";\n"); p += 4;
    fprint(fp,string(word(p),10)+";\n"); p += 4;
    fprint(fp,string(word(p),10)+";\n"); p += 4;
    break;
  case 1:
    fprint(fp,"/* text only */\n");
    fprint(fp,""+34+s12(p)+34+";\n"); p += 12;
    break;
  case 2:
  case 3:
    fprint(fp,""+34+s12(p)+34+";\n"); p += 12;
    break;
  case 256:
    fprint(fp,"/* no data */\n");
    fprint(fp,string(word(p),10)+";\n"); p += 4;
    fprint(fp,string(word(p),10)+";\n"); p += 4;
    fprint(fp,string(word(p),10)+";\n"); p += 4;
    break;
  case 257:
    fprint(fp,"/* text-only */\n");
  case 258:
  case 259:
    fprint(fp,"/* indirected */\n");
    fprint(fp,"@("+name+"_buf+"+string(word(p),10)+");\n"); p += 4;
    fprint(fp,"@("+name+"_buf+"+string(word(p),10)+");\n"); p += 4;
    fprint(fp,string(word(p),10)+";/* buffer length */\n"); p += 4;
    break;
  default:
    fclose(fp);
    quit("bad flags\n");
    break;
 }
 return p;
}

fprint(fp,s)
{
 local i;
 for (i = 0; i < sizeof(s); i++)
   putc(s[i],fp);
}

/* convert a number n to a string to base b */
string(n,b)  
{
 local neg,s,d;
 if (n == 0) return ("0");
 if (neg = (n<0)) n = -n;
 s = "";
 while (n)
   {
    d = n%b;
    s = ((d<10)?(d +'0'):(d+'W'))+s;
    n /= b;
   }
 return (((neg)?"-":"")+s);
}

hex(n)
{
 local s,byte,top,bottom,b,i,zero;
 s = "&";zero = TRUE;i = 4;
 b = @(newstring(4));
 in b put { n; }
 while (i>0 && zero)
   {
    i--;
    if (byte=byte(b+i)) zero = FALSE;
   }
 top = byte/16; bottom = byte%16;
 if (top) s += (top<10)?(top+'0'):(top+'W');
 s += (bottom<10)?(bottom+'0'):(bottom+'W'); 
 while (i>0)
   {
    i--; byte = byte(b+i); top = byte/16; bottom = byte%16;
    s += (top<10)?(top+'0'):(top+'W');
    s += (bottom<10)?(bottom+'0'):(bottom+'W');
   }
 return s;
}

/* 12 bytes of data */
s12(p)
{
 local i,s;
 s = newstring(12);
 for(i=0;i<12;i++)
    s[i] = byte(p+i);
 return s;
}

